package com.cardcaptorsakura.service.output;

import com.cardcaptorsakura.model.dto.ImageGenerationRequest;
import com.cardcaptorsakura.model.dto.ImageGenerationResponse;
import com.cardcaptorsakura.model.entity.PersonaConfig;
import com.cardcaptorsakura.service.persona.PersonaService;
import com.cardcaptorsakura.config.AIConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.image.ImageClient;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.image.ImageOptions;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.UUID;

/**
 * 图像生成服务
 * 负责根据文本描述生成图像，支持不同风格和尺寸
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ImageGenerationService {

    private final ImageClient imageClient;
    private final PersonaService personaService;
    private final AIConfig aiConfig;
    
    private static final String IMAGE_STORAGE_PATH = "uploads/generated-images/";
    private static final String[] SUPPORTED_FORMATS = {"png", "jpg", "jpeg", "webp"};

    /**
     * 生成图像
     *
     * @param request 图像生成请求
     * @return 图像生成响应
     */
    public ImageGenerationResponse generateImage(ImageGenerationRequest request) {
        try {
            // 1. 获取当前人格配置
            PersonaConfig persona = personaService.getActivePersona(request.getUserId());
            
            // 2. 构建个性化提示词
            String enhancedPrompt = enhancePromptWithPersona(request.getPrompt(), persona);
            
            // 3. 配置图像生成选项
            ImageOptions options = buildImageOptions(request);
            
            // 4. 调用AI模型生成图像
            ImagePrompt imagePrompt = new ImagePrompt(enhancedPrompt, options);
            ImageResponse response = imageClient.call(imagePrompt);
            
            // 5. 处理生成结果
            if (response.getResults().isEmpty()) {
                throw new RuntimeException("No image generated");
            }
            
            String imageUrl = response.getResult().getOutput().getUrl();
            String base64Data = response.getResult().getOutput().getB64Json();
            
            // 6. 保存图像文件
            String savedImagePath = saveGeneratedImage(base64Data, request.getUserId());
            
            log.info("Generated image for user: {}, persona: {}, prompt: {}", 
                    request.getUserId(), persona.getId(), request.getPrompt());
            
            return ImageGenerationResponse.builder()
                    .imageUrl(imageUrl)
                    .localPath(savedImagePath)
                    .prompt(enhancedPrompt)
                    .originalPrompt(request.getPrompt())
                    .width(request.getWidth())
                    .height(request.getHeight())
                    .style(request.getStyle())
                    .generatedAt(LocalDateTime.now())
                    .build();
            
        } catch (Exception e) {
            log.error("Error generating image for user: {}", request.getUserId(), e);
            throw new RuntimeException("Failed to generate image: " + e.getMessage(), e);
        }
    }

    /**
     * 根据人格增强提示词
     */
    private String enhancePromptWithPersona(String originalPrompt, PersonaConfig persona) {
        StringBuilder enhancedPrompt = new StringBuilder(originalPrompt);
        
        // 根据人格类型添加风格描述
        switch (persona.getId()) {
            case "doctor":
                enhancedPrompt.append(", medical illustration style, clean and professional, "
                        + "anatomically accurate, educational diagram style");
                break;
            case "chef":
                enhancedPrompt.append(", food photography style, appetizing and colorful, "
                        + "professional kitchen lighting, gourmet presentation");
                break;
            case "companion":
                enhancedPrompt.append(", warm and friendly style, soft lighting, "
                        + "comforting atmosphere, gentle colors");
                break;
        }
        
        // 添加通用质量提升词
        enhancedPrompt.append(", high quality, detailed, 4k resolution, professional");
        
        return enhancedPrompt.toString();
    }

    /**
     * 构建图像生成选项
     */
    private ImageOptions buildImageOptions(ImageGenerationRequest request) {
        return ImageOptions.builder()
                .withWidth(request.getWidth())
                .withHeight(request.getHeight())
                .withResponseFormat("b64_json")
                .build();
    }

    /**
     * 保存生成的图像
     */
    private String saveGeneratedImage(String base64Data, String userId) throws IOException {
        if (base64Data == null || base64Data.isEmpty()) {
            throw new IllegalArgumentException("No image data to save");
        }
        
        // 创建存储目录
        Path storageDir = Paths.get(IMAGE_STORAGE_PATH, userId);
        Files.createDirectories(storageDir);
        
        // 生成文件名
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String filename = String.format("generated_%s_%s.png", timestamp, UUID.randomUUID().toString().substring(0, 8));
        Path filePath = storageDir.resolve(filename);
        
        // 解码并保存图像
        byte[] imageBytes = Base64.getDecoder().decode(base64Data);
        Files.write(filePath, imageBytes);
        
        log.info("Saved generated image to: {}", filePath.toString());
        return filePath.toString();
    }

    /**
     * 图像风格转换
     */
    public ImageGenerationResponse convertImageStyle(String userId, String imagePath, String targetStyle) {
        try {
            // 读取原始图像
            Path path = Paths.get(imagePath);
            if (!Files.exists(path)) {
                throw new IllegalArgumentException("Image file not found: " + imagePath);
            }
            
            byte[] imageBytes = Files.readAllBytes(path);
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            
            // 构建风格转换提示词
            String stylePrompt = buildStylePrompt(targetStyle);
            
            // 获取人格配置
            PersonaConfig persona = personaService.getActivePersona(userId);
            String enhancedPrompt = enhancePromptWithPersona(stylePrompt, persona);
            
            // 执行风格转换（这里需要支持图像到图像的转换）
            // 注意：这需要支持img2img的AI模型
            ImageOptions options = ImageOptions.builder()
                    .withWidth(512)
                    .withHeight(512)
                    .withResponseFormat("b64_json")
                    .build();
            
            ImagePrompt imagePrompt = new ImagePrompt(enhancedPrompt, options);
            ImageResponse response = imageClient.call(imagePrompt);
            
            if (response.getResults().isEmpty()) {
                throw new RuntimeException("No styled image generated");
            }
            
            String resultBase64 = response.getResult().getOutput().getB64Json();
            String savedPath = saveGeneratedImage(resultBase64, userId);
            
            log.info("Converted image style for user: {}, style: {}", userId, targetStyle);
            
            return ImageGenerationResponse.builder()
                    .localPath(savedPath)
                    .prompt(enhancedPrompt)
                    .originalPrompt(stylePrompt)
                    .style(targetStyle)
                    .generatedAt(LocalDateTime.now())
                    .build();
            
        } catch (Exception e) {
            log.error("Error converting image style for user: {}", userId, e);
            throw new RuntimeException("Failed to convert image style: " + e.getMessage(), e);
        }
    }

    /**
     * 构建风格转换提示词
     */
    private String buildStylePrompt(String style) {
        switch (style.toLowerCase()) {
            case "anime":
                return "Convert to anime/manga art style, vibrant colors, detailed character design";
            case "realistic":
                return "Convert to photorealistic style, natural lighting, high detail";
            case "cartoon":
                return "Convert to cartoon style, bright colors, simplified forms";
            case "oil_painting":
                return "Convert to oil painting style, brush strokes, artistic texture";
            case "watercolor":
                return "Convert to watercolor painting style, soft edges, flowing colors";
            case "sketch":
                return "Convert to pencil sketch style, black and white, detailed lines";
            default:
                return "Apply artistic style transformation, enhance visual appeal";
        }
    }

    /**
     * 验证图像格式
     */
    public boolean isValidImageFormat(String filename) {
        if (filename == null || filename.isEmpty()) {
            return false;
        }
        
        String extension = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
        for (String format : SUPPORTED_FORMATS) {
            if (format.equals(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取用户生成的图像历史
     */
    public java.util.List<String> getUserImageHistory(String userId, int limit) {
        try {
            Path userDir = Paths.get(IMAGE_STORAGE_PATH, userId);
            if (!Files.exists(userDir)) {
                return new java.util.ArrayList<>();
            }
            
            return Files.list(userDir)
                    .filter(Files::isRegularFile)
                    .filter(path -> isValidImageFormat(path.getFileName().toString()))
                    .sorted((p1, p2) -> {
                        try {
                            return Files.getLastModifiedTime(p2).compareTo(Files.getLastModifiedTime(p1));
                        } catch (IOException e) {
                            return 0;
                        }
                    })
                    .limit(limit)
                    .map(Path::toString)
                    .collect(java.util.stream.Collectors.toList());
                    
        } catch (Exception e) {
            log.error("Error retrieving image history for user: {}", userId, e);
            return new java.util.ArrayList<>();
        }
    }
}